Skip to content

fix: Make session.user and session.groups accessible in modules and Express#2276

Open
cpsievert wants to merge 4 commits into
mainfrom
fix/session-user-groups-proxy
Open

fix: Make session.user and session.groups accessible in modules and Express#2276
cpsievert wants to merge 4 commits into
mainfrom
fix/session-user-groups-proxy

Conversation

@cpsievert

Copy link
Copy Markdown
Collaborator

Problem

session.user and session.groups raise AttributeError in any session context other than a root AppSession — which means module sessions and Express apps both fail silently or crash when app code tries to read the authenticated user's identity.

Minimal reproducible example (Express):

from shiny.express import session

print(session.user)  # AttributeError: 'ExpressStubSession' object has no attribute 'user'

Module session:

@module.server
def mod(input, output, session):
    print(session.user)  # AttributeError: 'SessionProxy' object has no attribute 'user'

The root cause was twofold:

  • ExpressStubSession never initialised user or groups
  • SessionProxy (used for module sessions) never delegated user/groups to its root session

Fix

Beyond just adding the missing attributes, this exposed a design gap: user and groups were plain mutable instance attributes on AppSession, which means nothing in the type system prevented app code from reassigning them. Since these represent authenticated identity derived from immutable HTTP headers, they should be read-only.

user and groups are now abstract read-only properties on the Session ABC, implemented concretely across all three session types:

  • AppSession: reads from private _user/_groups backing fields populated from credentials headers at connection time
  • SessionProxy: delegates to _root_session.user / _root_session.groups via property, so module sessions always reflect the root session's identity (including nested modules)
  • ExpressStubSession: returns None — no real HTTP connection, so no credentials

cpsievert and others added 4 commits June 29, 2026 16:49
…xpress

SessionProxy and ExpressStubSession both lacked user/groups, causing
AttributeError whenever app code read session.user outside of a root
AppSession (i.e. inside any module or Express app).

Beyond patching the missing attributes, user and groups are now abstract
read-only properties on the Session ABC. AppSession exposes them via
properties backed by private _user/_groups fields; SessionProxy delegates
to _root_session; ExpressStubSession returns None. This prevents app code
from mutating authenticated identity, which is derived from immutable HTTP
credentials headers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant